use std::{env, fs, path::PathBuf};

use axum::{
    extract::{Multipart, Path},
    response::Html,
};

/// 上传表单
pub async fn upload_file() -> Html<&'static str> {
    Html(
        r#"
        <!doctype html>
        <html>
            <head>
                <meta charset="utf-8">
                <title>上传文件</title>
            </head>
            <body>
                <form action="/upload" method="post" enctype="multipart/form-data">
                    <label>
                        上传文件：
                        <input type="file" name="file" id="file">
                    </label>
                    <button type="submit">上传文件</button>
                </form>
                <img id="img" src="" alt="">
                <script>
                    file.onchange = function(e) {
                        img.src = window.URL.createObjectURL(e.target.files[0]);
                    }
                </script>
            </body>
        </html>
        "#,
    )
}

// 上传文件
pub async fn upload(mut multipart: Multipart) -> String {
    let mut ret_file_name = String::from("");
    while let Some(field) = multipart.next_field().await.unwrap() {
        let file_name: String = field.file_name().unwrap().to_string();
        ret_file_name = file_name.clone();
        let data = field.bytes().await.unwrap();
        // 设置路径
        let mut root_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
        root_path.push(env::var("FILE_DIR").unwrap());
        root_path.push(&file_name);
        println!("{:?}", root_path.as_path().as_os_str());
        tokio::fs::write(root_path, &data)
            .await
            .expect("文件写入失败！");
    }
    let img_url = env::var("IMG_URL").expect("Not configured in .env");
    format!("{img_url}/{ret_file_name}")
}

// 只能显示一级文件列表
pub async fn show_files_root() -> Html<String> {
    Html(list_handler(None))
}
// 递归显示文件
pub async fn show_files_listing(Path(path): Path<String>) -> Html<String> {
    Html(list_handler(Some(path)))
}
// 资源目录处理
fn list_handler(path: Option<String>) -> String {
    // 资产目录
    let assets = env::var("FILE_DIR").unwrap();
    // 是否有path
    let prefix_path = match path {
        Some(path) => "/".to_string() + &path,
        None => "".to_string(),
    };

    let mut body = String::new();
    body.push_str("<html><body>");
    body.push_str(&format!("<h1>index of /static{}/</h1><ul>", prefix_path));
    let file_result = fs::read_dir(&format!("./{}{}", assets, prefix_path));
    // 如果不存在
    if file_result.is_err() {
        body.push_str("<h2>不存在的目录</h2>");
        body.push_str("</ul></body></html>");
        return body;
    }
    for entry in file_result.unwrap() {
        let file_path = entry.unwrap().path();
        let file_name = file_path.file_name().unwrap().to_str().unwrap();

        let prefix: &str = match file_path.is_file() {
            true => assets.as_str(), // 资源路径
            false => "static",       // 路由路径
        };
        body.push_str(&format!(
            "<li><a href='/{prefix}{prefix_path}/{file_name}'>{file_name}</a></li>"
        ));
    }
    body.push_str("</ul></body></html>");
    body
}
